﻿using MathNet.Numerics;
using SeeSharpTools.JY.DSP.Fundamental;
using SeeSharpTools.JY.DSP.SoundVibration;
using Sunny.UI;
using System;
using System.Data;
using System.Linq;

namespace SeeSharpTools.Demo
{
    public partial class FormSpectrumMeasure : UIPage
    {
        private bool isRunning = false;

        public FormSpectrumMeasure()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            double VmaxPk = 2;       // Maximum operating voltage
            double Fi = 2000;        // Sinusoidal frequency of 2 kHz
            double Fs = 44.1e3;      // Sample rate of 44.1kHz
            double Tstop = 50e-3;    // Duration of sinusoid
            double[] t = Generate.LinearRange(0, 1 / Fs, Tstop);

            // Use the maximum allowable voltage of the amplifier
            double[] input = t.Select(num => VmaxPk * Math.Sin(2 * Math.PI * Fi * num)).ToArray();

            // polynomial coefficients
            double a0 = 25e-3;  // dc bias(25mV)
            double a1 = 1;      // voltage gain
            double a2 = 6e-5;   // second order term
            double a3 = -1e-3;  // third order term
            double a4 = 5e-6;   // fourth order term
            double a5 = 1e-5;   // fifth order term
            double[] polyCoeff = new double[] { a0, a1, a2, a3, a4, a5 };

            // add noise at input
            double noiseVrms = 4e-4;  // RMS voltage of input noisefloor
            double[] inputNoise = new double[input.Length];
            Generation.UniformWhiteNoise(ref inputNoise, noiseVrms);
            double[] distortedInput = input.Zip(inputNoise, (a, b) => a + b).ToArray();

            // adjust input by DC bias, voltage gain and higher order terms
            //outputVoltage = polyval(polyCoeff, distortedInput);
            double[] output = new double[distortedInput.Length];
            for (int i = 0; i < output.Length; i++)
            {
                output[i] = Polynomial.Evaluate(distortedInput[i], polyCoeff);
            }

            easyChartX1.Plot(t, output);
            easyChartX1.AxisX.Title = "时间 (s)";
            easyChartX1.AxisY.Title = "幅度";

            // 计算功率谱
            double[] sp = new double[output.Length / 2];
            Spectrum.PowerSpectrum(output, Fs, ref sp, out double df, SpectrumUnits.dBV);
            easyChartX2.Plot(sp, 0, df);
            easyChartX2.AxisX.Title = "频率 (Hz)";
            easyChartX2.AxisY.Title = "功率谱";

            // 动态参数测量
            ToneAnalysisResult toneAnalysis = HarmonicAnalyzer.ToneAnalysis(output, 1 / Fs, 10, true);
            textBox_SNR.Text = toneAnalysis.SNR.ToString("f4");
            textBox_SINAD.Text = toneAnalysis.SINAD.ToString("f4");
            textBox_THD.Text = toneAnalysis.THD.ToString("f4");
            textBox_THDPlusN.Text = toneAnalysis.THDplusN.ToString("f4");
            textBox_NoiseFloor.Text = toneAnalysis.NoiseFloor.ToString("f4");
        }

        private void uiSymbolButton_Click(object sender, EventArgs e)
        {
            if (isRunning)
            {
                timer1.Stop();
                uiSymbolButton.Symbol = 61515;
                isRunning = false;
            }
            else
            {
                timer1.Start();
                uiSymbolButton.Symbol = 61516;
                isRunning = true;
            }
        }
    }
}